home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-08-16 | 39.2 KB | 1,453 lines |
- ;;; -*- PACKAGE:KERMIT; BASE: 8; IBASE: 8; MODE:LISP -*-
-
-
- ;******************************************************************************
- ; Copyright (c) 1984, 1985 by Lisp Machine Inc.
- ; Symbolics-specific portions Copyright (c) 1985 by Honeywell, Inc.
- ; Permission to copy all or part of this material is granted, provided
- ; that the copies are not made or distributed for resale, and the
- ; copyright notices and reference to the source file and the software
- ; distribution version appear, and that notice is given that copying is
- ; by permission of Lisp Machine Inc. LMI reserves for itself the
- ; sole commercial right to use any part of this KERMIT/H19-Emulator
- ; not covered by any Columbia University copyright. Inquiries concerning
- ; copyright should be directed to Mr. Damon Lawrence at (213) 642-1116.
- ;
- ; Version Information:
- ; LMKERMIT 1.0 -- Original LMI code, plus edit ;1; for 3600 port
- ;
- ; Authorship Information:
- ; Mark David (LMI) Original version, using KERMIT.C as a guide
- ; George Carrette (LMI) Various enhancements
- ; Mark Ahlstrom (Honeywell) Port to 3600 (edits marked with ";1;" comments)
- ;
- ; Author Addresses:
- ; George Carrette ARPANET: GJC at MIT-MC
- ;
- ; Mark Ahlstrom ARPANET: Ahlstrom at HI-Multics
- ; PHONE: (612) 887-4006
- ; USMAIL: Honeywell MN09-1400
- ; Computer Sciences Center
- ; 10701 Lyndale Avenue South
- ; Bloomington, MN 55420
- ;******************************************************************************
-
-
-
- ;;; This program is KERMIT-TERMINAL.
- ;;;
- ;;; This is to be used to make your lisp machine terminal
- ;;; act like it is an "H19" terminal.
- ;;;
- ;;; No flavors are defined in this file. None of this code
- ;;; depends on anything having to do with flavors, except
- ;;; in so far as the lisp machine graphics operations require.
- ;;; This code contains a refreshingly low density of "messages."
- ;;; This makes the code so simple, I consider it ALMOST self explanatory.
- ;;;
- ;;; No "special" window is required. That is, a lisp listener
- ;;; should do fine. A tv:minimum-window will not, of course, work.
- ;;;
- ;;; For the H19 graphics protocol, see the Zenith manual for
- ;;; the Z29 terminal, which is available from the documentation
- ;;; department of LMI.
- ;;; ("Z-29 user's & technical guide"
- ;;; Appendix B -- Zenith Mode Code Info
- ;;; 1983, Zenith Data Systems.)
- ;;;
- ;;;
-
-
-
-
- ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
- ;;; special variables
-
- ;;;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-
-
-
- ;;; To use this, you only need to bind three special variables:
-
- ;;; 1. *TERMINAL* This must be bound to a local input output window
- ;;; that gets input from the lisp machine's keyboard
- ;;; and mouse.
- ;;; 2. *SERIAL-STREAM*
- ;;; This must be bound to an serial stream (or some stream
- ;;; than supports the operations we use in this code.)
- ;;; To get this stream, on a Lambda Lisp Machine,
- ;;; you usually just call si:make-sdu-serial-stream
- ;;; with no arguments.
- ;;; 3. interaction-pane
- ;;; This is a pane in which to bind debug-io, trace-output, query-io, use
- ;;; the NETWORK key interactions and in general any thing not involved
- ;;; in normal terminal interaction.
- ;;; It will work (if you have a normal window for example) to just
- ;;; have this be the same stream as *terminal* is bound to. The requirement
- ;;; is that IT MUST BE AN EXPOSED WINDOW!!
- ;;;
-
-
- (DEFCONST *ESCAPE-DISPATCH-TABLE* (MAKE-HASH-TABLE))
-
-
- (DECLARE (SPECIAL INTERACTION-PANE
- kermit-frame ;1;
- ))
-
- (DEFCONST *SERIAL-STREAM* :unbound)
-
- (DEFCONST *TERMINAL* :unbound)
-
-
- (DEFCONST *BAD-ESCAPES* ())
-
-
- (defconst *local-echo-mode* nil)
-
-
- (DEFCONST *LOGFILE* NIL) ;where to log terminal session, if desired
-
-
- (DEFCONST TURN-ON-LOGGING? NIL)
-
-
-
- (DEFCONST *TERMINAL-DEBUG-MODE* NIL)
-
-
-
-
-
-
-
-
-
- ;;;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-
- ;;; TERMINAL GRAPHICS AND OUTPUT "PRIMITIVES"
-
- ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
-
-
-
- (DEFCONST *INSERT-FLAG* ())
-
-
-
- (DEFCONST *REVERSE-VIDEO-FLAG* ())
-
-
-
- (DEFCONST *CURSOR-SAVE* '(0 0))
-
-
-
- (DEFCONST *SYSTEM-POSITION* '(0 0))
-
-
- (DEFCONST *USE-BIT-7-FOR-META* NIL)
-
-
-
- (DEFCONST *AUTO-CR-ON-LF-FLAG* NIL)
-
-
-
- (DEFCONST *AUTO-LF-ON-CR-FLAG* NIL)
-
- ;1; #+3600
- ;1; (defconst *disable-outgoing-cr-to-crlf-conversion* t
- ;1; "Yes if you want return to just send a <cr> during terminal emulation.") ;1; see the following note
-
- ;1; **************** some experimental new stuff for 3600 ****************
- ;1;
- ;1; The 3600 ascii translation that is "build in" to all :ascii-character
- ;1; streams has the unfortunate convention of turning outgoing <return> characters
- ;1; into <CR><LF> pairs, and converting incoming <CR><LF> pairs in <return> characters.
- ;1; This is usually ok, but with certain hosts, it works better if <return> actually
- ;1; sends just a <CR>. For example, I found that I could only get proper Heath19
- ;1; emulation with our LAN and with Multics if I set *disable-return-to-crlf-conversion*
- ;1; and *auto-lf-on-cr-flag* to true.
-
- ;1; Note that this is pulled from >rel-6-sys>io>stream.lisp and modified...
- ;1; Also note that this should only be in effect when connected for terminal
- ;1; emulation. It must work in the usual way for file transfers, etc.
-
- ;1; #+3600
- ;1; (defvar kermit-connected-flag nil) ;1; defined in lmiwin.
-
- ;1; #+3600
- ;1; (DEFWHOPPER (si:ASCII-TRANSLATING-OUTPUT-STREAM-MIXIN :TYO) (CH)
- ;1; (COND ((and ;1; This first condition is the changed part.
- ;1; kermit-connected-flag ;1; if we are connected for terminal emulation and...
- ;1; (char= ch #\CR) ;1; char is <return> and...
- ;1; *disable-outgoing-cr-to-crlf-conversion*) ;1; and we want return to just send <cr>,
- ;1; (continue-whopper #O015)) ;1; then do it that way.
- ;1; ((CHAR= CH #\CR) ;1; This rest is the normal function...
- ;1; (CONTINUE-WHOPPER #O015)
- ;1; (CONTINUE-WHOPPER #O012))
- ;1; (T (CONTINUE-WHOPPER (CHAR-TO-ASCII CH)))))
-
-
- (DEFSUBST TERMINAL-INSERT-CHAR ()
- (SEND *TERMINAL* ':INSERT-CHAR 1 ':CHARACTER))
-
-
-
-
-
- (DEFSUBST TERMINAL-ERASE-ALUF ()
- (SEND *TERMINAL* ':ERASE-ALUF))
-
-
-
-
-
- (DEFSUBST TERMINAL-SET-ERASE-ALUF (ALU)
- (SEND *TERMINAL* ':SET-ERASE-ALUF ALU))
-
-
-
-
-
- (DEFSUBST TERMINAL-TYO (CHAR-CODE)
- (SEND *TERMINAL* ':TYO CHAR-CODE))
-
-
-
-
-
-
- (DEFSUBST TERMINAL-READ-CURSORPOS ()
- (SEND *TERMINAL* ':READ-CURSORPOS ':CHARACTER))
-
-
-
-
-
-
- (DEFSUBST TERMINAL-SET-CURSORPOS (X Y)
- (SEND *TERMINAL* ':SET-CURSORPOS
- X Y
- ':CHARACTER))
-
-
-
-
-
- (DEFSUBST TERMINAL-INSERT-LINE (&OPTIONAL (NTIMES 1))
- #+3600 (send *terminal* :insert-line ntimes) ;1; tv:sheet-insert-line is obsolete on 3600
- #-3600 (TV:SHEET-INSERT-LINE *TERMINAL* NTIMES))
-
-
-
-
-
-
- (DEFSUBST TERMINAL-DELETE-LINE (&OPTIONAL (NTIMES 1))
- #+3600 (send *terminal* :delete-line ntimes) ;1; tv:sheet-delete-line obsolete on 3600
- #-3600 (TV:SHEET-DELETE-LINE *TERMINAL* NTIMES))
-
-
-
-
-
-
- (DEFSUBST TERMINAL-CLEAR-CHAR ()
- (SEND *TERMINAL* ':CLEAR-CHAR))
-
-
-
-
-
-
-
-
-
- (DEFSUBST TERMINAL-CHARACTER-WIDTH ()
- (MULTIPLE-VALUE-BIND (WIDTH IGNORE)
- (SEND *TERMINAL* ':SIZE-IN-CHARACTERS)
- WIDTH))
-
-
-
-
-
-
- (DEFSUBST TERMINAL-CHARACTER-HEIGHT ()
- (MULTIPLE-VALUE-BIND (IGNORE HEIGHT)
- (SEND *TERMINAL* ':SIZE-IN-CHARACTERS)
- HEIGHT))
-
-
-
-
-
-
- (DEFSUBST TERMINAL-END-OF-PAGE-EXCEPTION ()
- (SEND *TERMINAL* ':HOME-CURSOR)
- (SEND *TERMINAL* ':DELETE-LINE)
- (TERMINAL-SET-CURSORPOS 0 (- (TERMINAL-CHARACTER-HEIGHT) 2)))
-
-
-
-
-
-
-
-
- (DEFSUBST TERMINAL-CR ()
- (MULTIPLE-VALUE-BIND (IGNORE Y)
- (TERMINAL-READ-CURSORPOS)
- (TERMINAL-SET-CURSORPOS 0 Y)
- (AND *AUTO-LF-ON-CR-FLAG*
- (COND ((EQ Y (- (TERMINAL-CHARACTER-HEIGHT) 2))
- (TERMINAL-END-OF-PAGE-EXCEPTION))
- (T (TERMINAL-SET-CURSORPOS 0 (1+ Y)))))
- NIL))
-
-
-
-
-
-
- (DEFSUBST TERMINAL-LINEFEED ()
- (MULTIPLE-VALUE-BIND (X Y)
- (TERMINAL-READ-CURSORPOS)
- (COND ((EQ Y (- (TERMINAL-CHARACTER-HEIGHT) 2))
- (TERMINAL-END-OF-PAGE-EXCEPTION))
- (T (TERMINAL-SET-CURSORPOS
- (IF *AUTO-CR-ON-LF-FLAG* 0 X)
- (1+ Y))))
- NIL))
-
-
-
-
-
-
-
- (defsubst serial-tyi ()
- (let ((ch? (send *serial-stream* ':tyi)))
- (and ch? (logand ch? #o177))))
-
-
-
-
- (DEFSUBST TERMINAL-SAVE-POS-1 ()
- (SETQ *SYSTEM-POSITION* (MULTIPLE-VALUE-LIST (TERMINAL-READ-CURSORPOS))))
-
-
-
-
- (DEFSUBST TERMINAL-RESTORE-POS-1 ()
- (TERMINAL-SET-CURSORPOS (CAR *SYSTEM-POSITION*) (CADR *SYSTEM-POSITION*)))
-
-
-
-
-
-
- (DEFSUBST TERMINAL-GOTO-BEG-OF-LINE ()
- (MULTIPLE-VALUE-BIND (IGNORE Y)
- (TERMINAL-READ-CURSORPOS)
- (TERMINAL-SET-CURSORPOS 0 Y)))
-
-
-
-
-
-
-
-
-
-
-
-
- (DEFSUBST TERMINAL-BACKSPACE ()
- (TERMINAL-TYO #\BACKSPACE))
-
-
-
- (DEFSUBST TERMINAL-BEEP ()
- (BEEP))
-
-
-
-
- (DEFSUBST TERMINAL-TAB ()
- (TERMINAL-TYO #\TAB))
-
-
-
-
-
-
-
-
-
-
-
-
- ;;;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-
- ;;; definition of DEF-TERMINAL-ESCAPE
-
- ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
-
-
-
-
- (DEFMACRO DEF-TERMINAL-ESCAPE (KEY-NUMBER NEED-TO-DEFINE-P FUNCTION-NAME &BODY BODY)
- (COND (NEED-TO-DEFINE-P
- `(PROGN 'COMPILE
- (PUTHASH ,KEY-NUMBER ',FUNCTION-NAME *ESCAPE-DISPATCH-TABLE*)
- (DEFUN ,FUNCTION-NAME () . ,BODY)))
- ('ALREADY-DEFINED-BY-SYSTEM-OR-USER
- `(PUTHASH ,KEY-NUMBER ',FUNCTION-NAME *ESCAPE-DISPATCH-TABLE*))))
-
-
-
- ;;;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-
- ;;; terminal escape definitions
-
- ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #/[ T TERMINAL-EAT-TEMP ; this may be wrong
- ;; 'Enter Hold Screen Mode' ZEHS
- (LET (I1 I2 FLAG)
- (SETQ I1 (SERIAL-TYI))
- (SETQ I2 (SERIAL-TYI))
- (COND ((EQ I1 #\?) (SETQ FLAG T) (SERIAL-TYI))
- ((OR (> I2 #\9) (< I2 #\0))
- (SETQ I1 (- I1 #\0)))
- (T (SETQ I1 (+ (* 10. (- I1 #\0)) (- I2 #\0)))
- (SETQ I2 (SERIAL-TYI))))
- (COND ((NOT FLAG)
- (SELECTQ I2
- (#\L (TERMINAL-INSERT-LINE I1))
- (#\M (TERMINAL-DELETE-LINE I1)))))))
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\\ T EXIT-EAT-TEMP
- (TERMINAL-CLEAR-SCREEN)) ; this may be wrong
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\H T TERMINAL-HOME-CURSOR
- (SEND *TERMINAL* ':HOME-CURSOR))
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\p T TERMINAL-REVERSE-VIDEO
- (SETQ *REVERSE-VIDEO-FLAG* T)
- NIL)
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\q T TERMINAL-NORMAL-VIDEO
- (SETQ *REVERSE-VIDEO-FLAG* NIL)
- NIL)
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\x T TERMINAL-SET-MODE
- (SELECTQ (SERIAL-TYI)
- (#O10 (SETQ *AUTO-LF-ON-CR-FLAG* T))
- (#O11 (SETQ *AUTO-CR-ON-LF-FLAG* T))
- (:OTHERWISE ()))
- (COND (*TERMINAL-DEBUG-MODE* (FORMAT INTERACTION-PANE "~% SET MODE: ~O [~C] ")))
- NIL)
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\y T TERMINAL-RESET-MODE
- (SELECTQ (SERIAL-TYI)
- (#O10 (SETQ *AUTO-LF-ON-CR-FLAG* NIL))
- (#O11 (SETQ *AUTO-CR-ON-LF-FLAG* NIL))
- (:OTHERWISE ()))
- (COND (*TERMINAL-DEBUG-MODE* (FORMAT INTERACTION-PANE "~% SET MODE: ~O [~C] ")))
- NIL)
-
-
-
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\C T TERMINAL-CURSOR-FORWARD
- (MULTIPLE-VALUE-BIND (X Y)
- (TERMINAL-READ-CURSORPOS)
- (UNLESS (EQ X 79.)
- (TERMINAL-SET-CURSORPOS (1+ X) Y))))
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\D T TERMINAL-CURSOR-BACKWARDS
- (MULTIPLE-VALUE-BIND (X Y)
- (TERMINAL-READ-CURSORPOS)
- (UNLESS (EQ X 0)
- (TERMINAL-SET-CURSORPOS (1- X) Y))))
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\B T TERMINAL-CURSOR-DOWN
- (MULTIPLE-VALUE-BIND (X Y)
- (TERMINAL-READ-CURSORPOS)
- (UNLESS (EQ Y (- (TERMINAL-CHARACTER-HEIGHT) 2))
- (TERMINAL-SET-CURSORPOS X (1+ Y)))))
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\A T TERMINAL-CURSOR-UP
- (MULTIPLE-VALUE-BIND (X Y)
- (TERMINAL-READ-CURSORPOS)
- (UNLESS (EQ Y 0)
- (TERMINAL-SET-CURSORPOS X (1- Y)))))
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\I T TERMINAL-REVERSE-INDEX
- (MULTIPLE-VALUE-BIND (X Y)
- (TERMINAL-READ-CURSORPOS)
- (COND ((ZEROP X)
- (TERMINAL-SET-CURSORPOS 0 (- (TERMINAL-CHARACTER-HEIGHT) 2))
- (TERMINAL-DELETE-LINE)
- (TERMINAL-SET-CURSORPOS X Y)
- (TERMINAL-INSERT-LINE))
- (T (TERMINAL-CURSOR-UP)))))
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\n T TERMINAL-REPORT-CURSOR
- (MULTIPLE-VALUE-BIND (X Y)
- (TERMINAL-READ-CURSORPOS)
- (SEND *SERIAL-STREAM* ':TYO #O33) ;33 is ascii <altmode>
- (SEND *SERIAL-STREAM* ':TYO #\Y)
- (SEND *SERIAL-STREAM* ':TYO (+ 32. Y))
- (SEND *SERIAL-STREAM* ':TYO (+ 32. X))))
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\J T TERMINAL-CLEAR-EOF
- (SEND *TERMINAL* #+3600 :clear-rest-of-window #-3600 ':CLEAR-EOF) ;1;
- )
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\j T TERMINAL-SAVE-POS
- (SETQ *CURSOR-SAVE*
- (MULTIPLE-VALUE-LIST (TERMINAL-READ-CURSORPOS))))
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\k T TERMINAL-RESTORE-POS
- (TERMINAL-SET-CURSORPOS (CAR *CURSOR-SAVE*) (CADR *CURSOR-SAVE*)))
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\Y T TERMINAL-SET-POS
- (LET ((Y (SERIAL-TYI))
- (X (SERIAL-TYI)))
- (cond (*terminal-debug-mode*
- (format t "~& setpos X=~D Y=~D" (- x 32.) (- y 32.))))
- (TERMINAL-SET-CURSORPOS (- X 32.) (- Y 32.))))
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\E T TERMINAL-CLEAR-SCREEN
- (SEND *TERMINAL* #+3600 :clear-window #-3600 ':CLEAR-SCREEN)) ;1;
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\b T TERMINAL-CLEAR-BOD
- (MULTIPLE-VALUE-BIND (X Y)
- (TERMINAL-READ-CURSORPOS)
- (DOTIMES (LINE (1- Y))
- (TERMINAL-SET-CURSORPOS 0 LINE)
- (TERMINAL-CLEAR-EOL))
- (TERMINAL-SET-CURSORPOS 0 Y)
- (DOTIMES (DUMMY X)
- (TERMINAL-CLEAR-CHAR)
- (TERMINAL-CURSOR-FORWARD))
- (TERMINAL-CURSOR-BACKWARDS)))
-
-
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\l T TERMINAL-CLEAR-LINE
- (MULTIPLE-VALUE-BIND (X Y)
- (TERMINAL-READ-CURSORPOS)
- (TERMINAL-SET-CURSORPOS 0 Y)
- (TERMINAL-CLEAR-EOL)
- (TERMINAL-SET-CURSORPOS X Y)))
-
-
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\o T TERMINAL-ERASE-BOL
- (MULTIPLE-VALUE-BIND (X Y)
- (TERMINAL-READ-CURSORPOS)
- (TERMINAL-SET-CURSORPOS 0 Y)
- (DOTIMES (DUMMY X)
- (TERMINAL-CLEAR-CHAR)
- (TERMINAL-CURSOR-FORWARD))
- (TERMINAL-CURSOR-BACKWARDS)))
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\K T TERMINAL-CLEAR-EOL
- (SEND *TERMINAL* #+3600 :clear-rest-of-line #-3600 ':CLEAR-EOL)) ;1;
-
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\L T TERMINAL-INSERT-ONE-LINE
- (TERMINAL-SAVE-POS-1)
- (TERMINAL-SET-CURSORPOS 0 (- (TERMINAL-CHARACTER-HEIGHT) 2))
- (TERMINAL-DELETE-LINE)
- (TERMINAL-RESTORE-POS-1)
- (TERMINAL-INSERT-LINE)
- (TERMINAL-GOTO-BEG-OF-LINE))
-
-
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\M T TERMINAL-DELETE-ONE-LINE
- (TERMINAL-DELETE-LINE)
- (TERMINAL-SAVE-POS-1)
- (TERMINAL-SET-CURSORPOS 0 (- (TERMINAL-CHARACTER-HEIGHT) 2))
- (TERMINAL-INSERT-LINE)
- (TERMINAL-RESTORE-POS-1)
- (TERMINAL-GOTO-BEG-OF-LINE))
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\N T TERMINAL-DELETE-CHAR
- (SEND *TERMINAL* ':DELETE-CHAR))
-
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\@ T TERMINAL-INSERT-MODE
- (SETQ *INSERT-FLAG* T)
- NIL)
-
-
-
-
-
-
-
-
- (DEF-TERMINAL-ESCAPE #\O T TERMINAL-EXIT-INSERT-MODE
- (SETQ *INSERT-FLAG* NIL))
-
-
-
-
- (DEFSUBST ESCAPE-DISPATCH ()
- (LET* ((KEYSTROKE (SERIAL-TYI))
- (METHOD (GETHASH KEYSTROKE *ESCAPE-DISPATCH-TABLE*)))
- (COND (METHOD
- (FUNCALL METHOD)
- (COND (*TERMINAL-DEBUG-MODE*
- (FORMAT INTERACTION-PANE "~% ~O [~:@C] ~S " KEYSTROKE KEYSTROKE METHOD))))
- (T (PUSH KEYSTROKE *BAD-ESCAPES*)
- (COND (*TERMINAL-DEBUG-MODE*
- (FORMAT INTERACTION-PANE "~% ~O [~C] <<*** BAD ESCAPE CHARACTER"
- KEYSTROKE KEYSTROKE)))))))
-
-
-
-
-
-
- (DEFUN READ-CHAR-FROM-SERIAL-STREAM-TO-TERMINAL ()
- (LET ((KEYSTROKE (SERIAL-TYI)))
-
- (COND ((EQ KEYSTROKE #O33) ;ASCII <ALTMODE> [ESCAPE]
- (ESCAPE-DISPATCH))
-
- ((< #O31 KEYSTROKE #O200)
- (AND *LOGFILE* TURN-ON-LOGGING? (SEND *LOGFILE* ':TYO KEYSTROKE)) ;LOGFILE KLUDGE
- (COND (*INSERT-FLAG* (TERMINAL-INSERT-CHAR)))
- (LET ((STORE (TERMINAL-ERASE-ALUF)))
- (TERMINAL-SET-ERASE-ALUF (IF *REVERSE-VIDEO-FLAG* TV:ALU-IOR TV:ALU-ANDCA))
- (TERMINAL-CLEAR-CHAR)
- (TERMINAL-SET-ERASE-ALUF STORE))
- (COND ((> (TERMINAL-READ-CURSORPOS) (TERMINAL-CHARACTER-WIDTH))
- (TERMINAL-CR)))
-
- (TERMINAL-TYO KEYSTROKE))
-
- (T (SELECTQ KEYSTROKE
- (#O7 (TERMINAL-BEEP))
- (#O10 (TERMINAL-BACKSPACE))
- (#O11 (TERMINAL-TAB)
- (AND *LOGFILE* TURN-ON-LOGGING? (SEND *LOGFILE* ':TYO #O211)))
- (#O12 (TERMINAL-LINEFEED))
- (#O15 (TERMINAL-CR)
- (AND *LOGFILE* TURN-ON-LOGGING? (SEND *LOGFILE* ':TYO #O215)))
- (T (COND (*TERMINAL-DEBUG-MODE*
- (FORMAT INTERACTION-PANE
- "~%Unrecognized /"control character/": ~O [~:@C]"
- KEYSTROKE KEYSTROKE))))
- )))))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (defun process-wait-listen (&rest streams)
- "waits on input on the streams, returns the stream which has input ready."
- (let ((stream1 (car streams)))
- (cond
- ((send stream1 ':listen) stream1)
- (t
- (with-stack-list (return-value nil)
- (process-wait "wait-listen"
- #'(lambda (return-value streams)
- (dolist (stream streams)
- (if (send stream ':listen)
- (return (setf (car return-value) stream)))))
- return-value
- streams)
- (car return-value))))))
-
-
-
-
-
-
-
-
- ;;; sending characters from terminal to serial-stream:
-
-
-
-
- (DEFSUBST TERMINAL-TYI ()
- (SEND *TERMINAL* ':TYI))
-
-
-
- (defsubst serial-tyo (char)
- (send *serial-stream* ':tyo char))
-
-
-
-
- ;;; this is now somewhat specialize for
- ;;; kermit by having this mouse menu tracking
- ;;; business, but its just the easiest way to
- ;;; keep the menu active while Connect is running.
- ;;; See the file "sys:kermit;kermit-window" for
- ;;; the extra meaning to this.
-
-
-
- (defsubst terminal-any-tyi ()
- (send *terminal* ':any-tyi))
-
- (defun read-char-from-keyboard-to-serial-stream ()
- (declare (special *escchr*))
- (let ((key-stroke (terminal-any-tyi)))
- (cond ((and (not (atom key-stroke)) (eq (car key-stroke) ':menu))
- (funcall (cadddr key-stroke) ':execute (cadr key-stroke)))
- ((not (fixnump key-stroke)) (beep))
- (t (if *local-echo-mode*
- (format *terminal* "~C" key-stroke))
- (when (memq (ldb %%kbd-char key-stroke) '(#\Rubout #+(not 3600) #\Delete)) ;1;
- (setq key-stroke (dpb 177 %%kbd-char key-stroke)))
- (select key-stroke
- (*escchr* (network-keystroke-handler))
- (#\Call (serial-tyo #\ )) ; send a [top-c] (for ascii ctrl-z)
- #+3600
- (#\Escape (serial-tyo #o33)) ;1; send escape character, too.
- (t (let
-
- ((char (ldb %%kbd-char key-stroke))
- (control (ldb %%kbd-control key-stroke))
- (meta (ldb %%kbd-meta key-stroke)))
-
- (cond ((and (eq meta 1) (eq control 1))
- (serial-tyo
- #+3600 #\c-Z ;1; Will this do it??
- #-3600 #\top-c) ;; [TOP-C] IS An Ascii CTRL-Z
- (serial-tyo char))
- (t (cond ((eq control 1) (setq char (logand char 37))))
- (cond ((not (zerop meta))
- (cond (*use-bit-7-for-meta*
- (setq char (logior #o200 (logand char #o177))))
- (t (serial-tyo #o33)
- (setq char (logior char #o40))))))
- (serial-tyo char)))
- nil)))))))
-
-
-
-
-
-
-
- (defun network-keystroke-handler ()
- (declare (special kermit-frame *escchr*))
- (terminal-network-prompt) ;PROMPT THE USER
-
- (let ((terminal-io interaction-pane))
-
- ;1; I think that tv:with-selection-substitute on LMI would substitute kermit-frame for
- ;1; interaction-pane if interaction-pane is unbound, so that is what I will explicitly do for 3600.
- (#-3600 tv:with-selection-substitute #-3600 (interaction-pane kermit-frame)
- #+3600 let #+3600 ((interaction-pane (if (boundp 'interaction-pane) interaction-pane kermit-frame)))
-
- (let ((key-stroke (char-upcase (terminal-tyi))))
-
- (unless (eq key-stroke #\rubout)
- (format interaction-pane "~:@C" key-stroke))
-
- (condition-case ()
-
- (prog1 ; hey, return ':close sometimes
- (selectq key-stroke
-
- (#\CLEAR-SCREEN (terminal-clear-screen))
- (#\CONTROL-CLEAR-SCREEN (send interaction-pane
- #+3600 :clear-window ;1; clear-screen is
- #-3600 ':clear-screen)) ;1; obsolete on 3600
- ((#\HELP #/H) (terminal-network-help))
- (#\SPACE nil)
- (#\control-y (terminal-control-y-pop-up-ed-string-hack))
- (#/E (terminal-read-eval-print))
- (#\control-d
- (format t "~&Turning ~A Terminal Debug mode.~%"
- (if (setq *terminal-debug-mode* (not *terminal-debug-mode*))
- "ON" "OFF")))
- (#/D (format t "~&Turning ~A Local Echo mode.~%"
- (if (setq *local-echo-mode* (not *local-echo-mode*))
- "ON" "OFF")))
- (#\CONTROL-B (terminal-get-and-set-new-baud-rate))
- (#\CONTROL-S (terminal-set-status-of-connection))
- (#\STATUS (terminal-show-status-of-connection))
- (#/F (terminal-flush-input-buffer))
- (#/L (terminal-start-logging))
- (#\C-L (terminal-close-logging))
- (#/K (format interaction-pane "...closing stream ~S..."
- *serial-stream*)
- (send *serial-stream* ':close ':abort)
- (format interaction-pane "and disconnecting.~%")
- ':close)
-
- ;;KERMIT PROTOCOL:
-
- (#/0 (terminal-transmit-nul))
- (#/B (terminal-transmit-break))
- (#/C (format interaction-pane "...disconnecting.~%")
- ':close)
- (#/P (terminal-push-to-system-command-processor))
- (#/Q (terminal-quit-logging))
- (#/R (terminal-resume-logging))
- (#/S (terminal-show-status-of-connection))
- (#/? (terminal-network-help))
- (#\NETWORK (terminal-transmit-network-escape-character))
- (#\RUBOUT) ;do nothing
- (:otherwise (if (eq key-stroke kermit:*escchr*)
- (terminal-transmit-network-escape-character)
- (if (not (eq key-stroke #\RUBOUT))
- (format interaction-pane
- " <-- ?? Unknown argument to <NETWORK> ??")))))
- (terpri interaction-pane))
- (sys:abort nil))))))
-
-
- (defun terminal-control-y-pop-up-ed-string-hack ()
- (let
- ((string-to-transmit? ;null if aborted
- (zwei:pop-up-edstring ""
- '(:mouse)
- ()
- (- (tv:sheet-inside-right *terminal*)
- (tv:sheet-inside-left *terminal*))
- (- (tv:sheet-inside-bottom *terminal*)
- (tv:sheet-inside-top *terminal*))
- "Edit Text and hit <END> to transmit.")))
- (if string-to-transmit?
- (loop for i from 0 below (array-active-length string-to-transmit?)
- as char = (aref string-to-transmit? i)
- doing (send *serial-stream* ':tyo char)))))
-
- (DEFUN TERMINAL-NETWORK-HELP ()
- ;1; with-help-stream not on 3600...
- (#-3600 SI:WITH-HELP-STREAM #-3600 (S :LABEL '(:STRING "Terminal Network Help"
- :FONT FONTS:METSI :TOP :CENTERED)
- :SUPERIOR *TERMINAL*)
- #+3600 with-kermit-typeout-stream #+3600 S #+3600 '(:STRING "Terminal Network Help"
- :FONT FONTS:METSI :TOP)
- #-3600
- (FORMAT S "
- Single-keystroke Arguments to the <NETWORK> escape:
-
- C Close -- escape back to kermit command level
- <ctrl> Y Yank some text into a pop up window and send it thru serial stream
- <ctrl> D Debug toggle -- toggles terminal debug mode
- D Duplex toggle -- switch between local and remote terminal echoing
- K Kill stream -- send current stream a :close message and disconnect
- <clear-screen> Clear terminal screen
- <ctrl><clear> Clear interaction screen
- F Flush serial input buffer
- <ctrl>B Control Baud -- set baud rate
- E Eval -- evaluate lisp expression
- P Push -- break to lisp. Hit <resume> to return
- B Transmit a break
- 0 Transmit a nul
- s,<status> Show serial stream status
- L Log connection in a disk file
- <control>L Close logging to disk file
- Q Quit logging temporarily
- R Resume logging
- ?,<help>,h type this stuff ~%")
-
- #+3600
- (FORMAT S "
- Single-keystroke Arguments to the <NETWORK> escape:
-
- C Close -- escape back to kermit command level
- <ctrl> Y Yank some text into a pop up window and send it thru serial stream
- <ctrl> D Debug toggle -- toggles terminal debug mode
- D Duplex toggle -- switch between local and remote terminal echoing
- K Kill stream -- send current stream a :close message and disconnect
- <refresh> Clear terminal screen
- <ctrl><refresh> Clear interaction screen
- F Flush serial input buffer
- <ctrl>B Control Baud -- set baud rate
- E Eval -- evaluate lisp expression
- P Push -- break to lisp. Hit <resume> to return
- B Transmit a break
- 0 Transmit a nul
- S Show serial stream status
- L Log connection in a disk file
- <control>L Close logging to disk file
- Q Quit logging temporarily
- R Resume logging
- ?,<help>,h Help, type this stuff ~%")
- ))
-
-
-
- (defun toggle-duplex ()
- (format t "~&Local Echo mode being turned ~A.~%"
- (if *local-echo-mode* "OFF" "ON"))
- (setq *local-echo-mode* (not *local-echo-mode*)))
-
- (defun terminal-flush-input-buffer ()
- (send *serial-stream* ':clear-input))
-
- ;;; this macro here because this gets compiled first (before kermit-window).
-
- (defmacro with-second-font-and-more-processing (window &body body)
- "sets window's font to its second font and turns on more processing during body.
- sets them back to the way they were afterwards."
- (let ((font (gensym))
- (more-p (gensym)))
-
- `(let ((,font (send ,window ':current-font))
- (,more-p (send ,window ':more-p)))
- (unwind-protect
- (progn
- (send ,window ':set-current-font 1)
- (send ,window ':set-more-p t)
- ,@body)
- (send ,window ':set-current-font ,font)
- (send ,window ':set-more-p ,more-p)))))
-
- (DEFUN TERMINAL-TRANSMIT-NETWORK-ESCAPE-CHARACTER ()
- (declare (special *escchr*))
- (serial-tyo *escchr*))
-
-
-
- (defun terminal-show-status-of-connection ()
- ;1; Once again, I changed this since 3600 doesn't have with-help-stream.
- (#-3600 si:with-help-stream #-3600 (standard-output
- :label `(:string "Terminal Status"
- ,@(if (boundp 'fonts:metsi)
- '(:font fonts:metsi))
- :top :centered)
- :superior *terminal*)
- #+3600 with-kermit-typeout-stream #+3600 standard-output
- #+3600 `(:string "Terminal Status"
- ,@(if (boundp 'fonts:metsi) '(:font fonts:metsi)) :top)
- ;; status of logging:
- (format t "~&Logging is ~A~A."
- (if *logfile* "ON" "OFF")
- (if *logfile*
- (if turn-on-logging? " and ENABLED" " but DISABLED")
- ""))
- ;; and show logfile name if any:
- (if *logfile*
- (format t "~&Logfile name is: ~A" *logfile*))
- ;; status of echo:
- (format t "~&Local-echo-mode is ~A."
- (if *local-echo-mode* "ON" "OFF"))
- ;; terminal sizes:
- (let ((font (send *terminal* ':current-font)))
- (format t "~&Terminal sizes:~% Height: ~D lines; ~D pixels per line.~A"
- (terminal-character-height)
- (tv:font-char-height font)
- (format nil "~% Width: ~D characters; ~D pixels per character."
- (terminal-character-width)
- (tv:font-char-width font))))
-
- ;; line status:
- (cond
- #-3600 ((typep *serial-stream* 'unix:unix-stream) ;1; no unix package on 3600
- (describe *serial-stream*))
- #-3600 ((typep *serial-stream* 'si:sdu-serial-stream) ;1; no sdu stuff on 3600
- (format t "~%baud rate of ~A: ~d"
- *serial-stream*
- (send *serial-stream* ':baud-rate))
- (si:sdu-serial-status))
- ((typep *serial-stream* 'si:serial-stream)
- (format t "~%baud rate of ~A: ~d"
- *serial-stream*
- (send *serial-stream* ':get ':baud))
- #-3600 (si:serial-status) ;1; no serial-status on 3600, so guess at what it describes...
- #+3600 (progn
- (format t "~%parity is ~d ~
- ~%number of data bits is ~d ~
- ~%number of stop bits is ~d ~
- ~%xon-xoff protocol is ~d"
- (send *serial-stream* ':get ':parity)
- (send *serial-stream* ':get ':number-of-data-bits)
- (send *serial-stream* ':get ':number-of-stop-bits)
- (send *serial-stream* ':get ':xon-xoff-protocol)))
- )
- (t (describe *serial-stream*)))
-
- ))
-
-
-
-
- ;;; LOGGING: here it is.
-
- ;;; All we do is this: if the incoming character from the
- ;;; serial stream is a printing ascii character, we put it
- ;;; in the log file. Printing characters are in the range
- ;;; 32 to 177 plus 11, 14, and 15 (octal). Linefeeds and any
- ;;; other control characters are not sent. No input from the
- ;;; user's side is included whatsoever. The code for the actual
- ;;; capture of characters is thus isolated within the function
- ;;; read-char-from-serial-stream-to-terminal.
-
-
-
-
-
- (defun terminal-start-logging ()
- (cond (*logfile*
- (format interaction-pane "~& Cannot open a new logfile!!")
- (tv:beep))
- ((setq *logfile*
- (open (terminal-get-logfile-name-from-user) '(:out)))
- (setq turn-on-logging? t)
- (format interaction-pane "~& Logging output to file ~A~%"
- (send *logfile* ':truename)))
- (t (format interaction-pane "~& Unable to open logfile.")
- (tv:beep)))
- nil)
-
-
-
-
-
-
-
-
-
-
-
-
- (defun terminal-get-logfile-name-from-user ()
- (let ((default-pathname
- (fs:merge-pathname-defaults
- "TERMINAL.LOG"
- (if (and (boundp 'kermit-default-pathname) ;1; added :unbound check
- (neq kermit-default-pathname :unbound))
- kermit-default-pathname
- (fs:user-homedir)))))
- (fs:merge-pathname-defaults
- (prompt-and-read
- ':string-trim
- (format nil
- "~&Name log file: (DEFAULT: ~A) " ;1; just removed ">" from end...
- default-pathname))
- default-pathname)))
-
-
-
-
-
-
-
-
-
-
-
- (defun terminal-quit-logging ()
- (cond ((and *logfile* turn-on-logging?)
- (format interaction-pane
- "~&Turning off logged output to ~A~%"
- (send *logfile* ':truename))
- (setq turn-on-logging? nil))
- ((not *logfile*)
- (format interaction-pane
- "~& ?? There is no logging being done.~%"))
- ((not turn-on-logging?)
- (format interaction-pane
- "~& ?? Logging is not turned on.~%"))))
-
-
-
-
-
-
-
-
-
-
-
-
- (DEFUN TERMINAL-RESUME-LOGGING ()
- (COND ((AND *LOGFILE* (NOT TURN-ON-LOGGING?))
- (FORMAT INTERACTION-PANE "~&Turning on logged output to ~A~%"
- (SEND *LOGFILE* ':TRUENAME))
- (SETQ TURN-ON-LOGGING? T))
- ((NOT *LOGFILE*)
- (FORMAT INTERACTION-PANE
- "~& ?? There is no logging being done.~%"))
- (TURN-ON-LOGGING?
- (FORMAT INTERACTION-PANE
- "~& ?? Logging is not turned off.~%"))))
-
-
-
-
-
-
-
-
-
- (DEFUN TERMINAL-CLOSE-LOGGING ()
- (COND (*LOGFILE*
- (FORMAT INTERACTION-PANE "~&Closing logged output to ~A" (SEND *LOGFILE* ':TRUENAME))
- (SEND *LOGFILE* ':CLOSE)
- (SETQ *LOGFILE* NIL)
- (SETQ TURN-ON-LOGGING? NIL))
- (T (FORMAT INTERACTION-PANE
- " ?? There is no log file to close~%"))))
-
-
- #-common
- (DEFUN TERMINAL-PUSH-TO-SYSTEM-COMMAND-PROCESSOR ()
- (LET ((TERMINAL-IO INTERACTION-PANE))
- (BREAK KERMIT)))
-
- #+common
- (DEFUN TERMINAL-PUSH-TO-SYSTEM-COMMAND-PROCESSOR ()
- (LET ((TERMINAL-IO INTERACTION-PANE))
- (BREAK "Kermit Break while in Connect.")))
-
-
-
-
-
-
-
- (DEFUN TERMINAL-TRANSMIT-NUL ()
- (SERIAL-TYO 0))
-
- (DEFUN TERMINAL-CLOSE-CONNECTION ()
- NIL)
-
-
-
-
-
-
-
-
- (DEFUN TERMINAL-GET-AND-SET-NEW-BAUD-RATE () ;1; had to change this since 3600 will not be object-code compatible,
- (LET (TO-WHAT) ;1; and does not have stuff for selecting processor type.
- #-3600 (SELECTOR SI:PROCESSOR-TYPE-CODE EQ
- (SI:LAMBDA-TYPE-CODE
- (SEND *SERIAL-STREAM*
- ':SET-BAUD-RATE
- (IF (ZEROP (SETQ TO-WHAT
- (PROMPT-AND-READ ':NUMBER
- "~%The current baud rate is ~D. Answering with 0 keeps it.~%Baud rate? >>"
- (SEND *SERIAL-STREAM* ':BAUD-RATE))))
- (SEND *SERIAL-STREAM* ':BAUD-RATE)
- TO-WHAT)))
- (SI:CADR-TYPE-CODE
- (SEND *SERIAL-STREAM*
- ':PUT
- ':BAUD
- (IF (ZEROP (SETQ TO-WHAT
- (PROMPT-AND-READ ':NUMBER
- "~%The current baud rate is ~D. Answering with 0 keeps it.~%Baud rate? >>"
- (SEND *SERIAL-STREAM* ':GET ':BAUD))))
- (SEND *SERIAL-STREAM* ':GET ':BAUD)
- TO-WHAT))))
- #+3600 (SEND *SERIAL-STREAM*
- ':PUT
- ':BAUD
- (IF (ZEROP (SETQ TO-WHAT
- (PROMPT-AND-READ ':NUMBER
- "~%The current baud rate is ~D. Answering with 0 keeps it.~%Baud rate? >>"
- (SEND *SERIAL-STREAM* ':GET ':BAUD))))
- (SEND *SERIAL-STREAM* ':GET ':BAUD)
- TO-WHAT))
- ))
-
-
-
-
-
-
- (DEFUN TERMINAL-SET-STATUS-OF-CONNECTION ()
- NIL)
-
-
-
-
-
-
-
-
-
-
- (DEFUN TERMINAL-READ-EVAL-PRINT ()
- (FORMAT INTERACTION-PANE "~%EVAL>")
- (LET ((DEBUG-IO INTERACTION-PANE)
- (QUERY-IO INTERACTION-PANE)
- (ERROR-OUTPUT INTERACTION-PANE)
- (TERMINAL-IO INTERACTION-PANE)
- (STANDARD-INPUT INTERACTION-PANE)
- (STANDARD-OUTPUT INTERACTION-PANE))
- (CONDITION-CASE ()
- (PRINT (EVAL (READ)))
- (SYS:ABORT NIL))))
-
-
-
-
-
-
-
-
-
-
-
- #-3600
- (DEFUN TERMINAL-TRANSMIT-BREAK ()
-
- ;;PUT ASCII NUL [0] ON LINE FOR 1/4 SECOND
- ;1; Weird, but for 3600, the first parameter to time-difference
- ;1; is assumed to be later than the second, so had to change this.
- ;1; But.... this still doesn't work.... what you need is next version.
- (LOOP WITH TIME = (TIME)
- DOING (COND ((> #-3600 (TIME-DIFFERENCE TIME (TIME))
- #+3600 (time-difference (time) time)
- 15.)
- (RETURN))
- (T (SERIAL-TYO 0)))))
-
- #+3600
- (defun terminal-transmit-break ()
- (send *serial-stream* :send-break)) ;1; makes sense...
-
- (DEFUN TERMINAL-NETWORK-PROMPT ()
- (FORMAT INTERACTION-PANE "~&NETWORK>"))
-
-
-
-
-
- ;1; The defaults for these instance variable seem to have to be set here,
- ;1; as well as in the defconst/defvar of the corresponding globals.
- ;1; If not, they appear to take the global value when not connected,
- ;1; and the following value during connection.
-
- (defflavor kterm-state
- ;; analogous to kstate.
- ;; these are all used free by connect & its subroutines.
- ((*logfile* nil)
- (turn-on-logging? nil)
- (*local-echo-mode* nil)
- (*terminal-debug-mode* nil)
- (*insert-flag* nil)
- (*reverse-video-flag* nil)
- (*cursor-save* '(0 0))
- (*system-position* '(0 0))
- (*use-bit-7-for-meta* nil)
- (*auto-cr-on-lf-flag* nil)
- (*auto-lf-on-cr-flag* nil) ;1; accidentally left out?
- )
- ()
- :special-instance-variables)
-
-
- ;; for kermit window interface to call
-
- (defmethod (kterm-state :make-connection)
- (serial-stream terminal-stream)
- ;; now all the special instance variables are bound.
- (connect serial-stream terminal-stream))
-
-
- ;;;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
- ;;; CONNECT
- ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
-
-
-
-
-
-
-
- (defun connect
-
- ;; bind various streams
-
- (*serial-stream* *terminal*
-
- &optional
- (error-output error-output)
- (debug-io debug-io)
-
- &aux
- (interaction-pane (if (boundp 'interaction-pane)
- interaction-pane *terminal*))
- (*ttyfd* *serial-stream*))
-
- "Make *terminal* a virtual terminal connected with *serial-stream*, a serial stream.
-
- A simulation of a Heath//H19//Z29 terminal is attempted
- for communication with ASCII terminals. Do <NETWORK> <HELP>
- for help and feature explanation. <Network>C to Close (disconnect)"
- (declare (special *ttyfd*))
-
- (let ((char-aluf (send *terminal* ':char-aluf)))
-
- (loop initially
-
- (send *terminal* ':set-char-aluf tv:alu-xor)
-
- with winner = (process-wait-listen *serial-stream* *terminal*)
-
- doing
-
- (cond ((eq winner *serial-stream*)
- (read-char-from-serial-stream-to-terminal)
- (setq winner (process-wait-listen *terminal* *serial-stream*)))
-
- (t (cond ((eq (read-char-from-keyboard-to-serial-stream) ':close)
- (loop-finish)) ; we're done
- (t (setq winner (process-wait-listen *serial-stream* *terminal*))))))
-
- finally
- (send *terminal* ':set-char-aluf char-aluf)
- (return nil))))
-